package com.cheetah.utils;

import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.Map;

/**
 * @Author Administrator
 * @Date 2019/9/13
 * @Version V1.0
 * @Description:
 **/
@Slf4j
public class TokenUtil {

    public static String getToken() {
        return getToken(null);
    }

    public static String getToken(Map<String,Object> claims) {

        try {
            ClassPathResource resource =  new ClassPathResource("keys/pri.key");
            String key = getKey(resource);

            if(StringUtils.isBlank(key)){
                log.warn("没有找到秘钥！");
                return null;
            }

            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;

            // 生成签名密钥
            byte[] keyBytes = Base64.decodeBase64(key);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

            JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
                    .setIssuer("cheetah")
                    .setIssuedAt(new Date())
                    .signWith(signatureAlgorithm, privateKey);

            if(claims != null){
                claims.forEach((k,v) -> {
                    builder.claim(k,v);
                });
            }
            return builder.compact();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            log.error(e.getMessage(),e);
        }

        return null;
    }


    public static Jws<Claims>  parseToken(String token){
        try {
            // 读取公钥
            ClassPathResource resource =  new ClassPathResource("keys/pub.key");
            String key = getKey(resource);
            // 生成签名公钥
            byte[] keyBytes = Base64.decodeBase64(key);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            return Jwts.parser()
                    .setSigningKey(publicKey)
                    .parseClaimsJws(token);

        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
            log.error(e.getMessage(),e);
        }

        return null;
    }

    private static String getKey(ClassPathResource resource) {
        InputStream in = null;
        String key = "";
        try {
            in = resource.getInputStream();

            key = IOUtils.toString(in, "UTF-8").replaceAll("-----(.*)-----","").replaceAll("\r\n","");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return key;
    }

}
